// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.config;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.liuxinlong.enums.DataSourceEnum;
import com.liuxinlong.multiple.MultipleDataSource;
import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;

/**
 * MyBatisPlusConfiguration
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022年2月22日
 */
@Configuration
@MapperScan("com.aos.modules.mapper*")
public class MyBatisPlusConfiguration {

    /*
     * 分页插件，自动识别数据库类型 多租户，请参考官网【插件扩展】
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 开启 PageHelper 的支持
        paginationInterceptor.setLocalPage(true);
        return paginationInterceptor;
    }

    /**
     * SQL执行效率插件
     */
    @Bean
    @Profile({"dev", "qa"}) // 设置 dev test 环境开启
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(1000);
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }

    @Bean(name = "pmip")
    @ConfigurationProperties(prefix = "spring.datasource.druid.pmip")
    public DataSource pmip() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "qad")
    @ConfigurationProperties(prefix = "spring.datasource.druid.qad")
    public DataSource qad() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "htp")
    @ConfigurationProperties(prefix = "spring.datasource.druid.htp")
    public DataSource htp() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "ecn")
    @ConfigurationProperties(prefix = "spring.datasource.druid.ecn")
    public DataSource ecn() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "pdm")
    @ConfigurationProperties(prefix = "spring.datasource.druid.pdm")
    public DataSource pdm() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "pgs")
    @ConfigurationProperties(prefix = "spring.datasource.druid.pgs")
    public DataSource pgs() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "pmp")
    @ConfigurationProperties(prefix = "spring.datasource.druid.pmp")
    public DataSource pmp() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 动态数据源配置
     *
     * @return
     */
    @Bean
    @Primary
    public DataSource multipleDataSource(@Qualifier("pmip") DataSource pmip, @Qualifier("qad") DataSource qad,
                                         @Qualifier("htp") DataSource htp, @Qualifier("ecn") DataSource ecn,
                                         @Qualifier("pdm") DataSource pdm, @Qualifier("pgs") DataSource pgs,
                                         @Qualifier("pmp") DataSource pmp) {
        MultipleDataSource multipleDataSource = new MultipleDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceEnum.PMIP.getValue(), pmip);
        targetDataSources.put(DataSourceEnum.QAD.getValue(), qad);
        targetDataSources.put(DataSourceEnum.HTP.getValue(), htp);
        targetDataSources.put(DataSourceEnum.ECN.getValue(), ecn);
        targetDataSources.put(DataSourceEnum.PDM.getValue(), pdm);
        targetDataSources.put(DataSourceEnum.PGS.getValue(), pgs);
        targetDataSources.put(DataSourceEnum.PMP.getValue(), pmp);

        // 添加数据源
        multipleDataSource.setTargetDataSources(targetDataSources);
        // 设置默认数据源
        multipleDataSource.setDefaultTargetDataSource(pmip);
        return multipleDataSource;
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(multipleDataSource(pmip(), qad(), htp(), ecn(),pdm(),pgs(),pmp()));
        sqlSessionFactory.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*Mapper.xml"));

        MybatisConfiguration configuration = new MybatisConfiguration();
        // configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactory.setConfiguration(configuration);
        sqlSessionFactory.setPlugins(new Interceptor[]{ // PerformanceInterceptor(),OptimisticLockerInterceptor()
                paginationInterceptor() // 添加分页功能
        });
        // sqlSessionFactory.setGlobalConfig(globalConfiguration());
        return sqlSessionFactory.getObject();
    }

    /*
     * @Bean public GlobalConfiguration globalConfiguration() { GlobalConfiguration
     * conf = new GlobalConfiguration(new LogicSqlInjector());
     * conf.setLogicDeleteValue("-1"); conf.setLogicNotDeleteValue("1");
     * conf.setIdType(0); //conf.setMetaObjectHandler(new MyMetaObjectHandler());
     * conf.setDbColumnUnderline(true); conf.setRefresh(true); return conf; }
     */
}